package tgc.edu.exam.web.controller;

import java.util.HashSet;
import java.util.List;
import java.util.UUID;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import tgc.edu.exam.custom.CommonController;
import tgc.edu.exam.custom.DataGridParam;
import tgc.edu.exam.custom.DataGridUtils;
import tgc.edu.exam.custom.LayUiResult;
import tgc.edu.exam.custom.TablePageable;
import tgc.edu.exam.entity.CurriculumPlan;
import tgc.edu.exam.entity.Evaluation;
import tgc.edu.exam.entity.EvaluationInformation;
import tgc.edu.exam.entity.Student;
import tgc.edu.exam.entity.TbCurriculum;
import tgc.edu.exam.security.UserUtils;
import tgc.edu.exam.service.CurriculumPlanService;
import tgc.edu.exam.service.EvaluationInformationService;
import tgc.edu.exam.service.EvaluationService;
import tgc.edu.exam.service.StudentService;
import tgc.edu.exam.service.TbClassService;
import tgc.edu.exam.service.TbCurriculumService;
import tgc.edu.exam.web.form.EvaluationInformationForm;

@Controller
@RequestMapping(value="/evaluationInformation")
public class EvaluationInformationController extends CommonController<EvaluationInformation, UUID, EvaluationInformationForm> {
	@Autowired
	private EvaluationInformationService efService;
	@Autowired
	private TbCurriculumService tcService;
	@Autowired
	private UserUtils userUtils;
	@Autowired
	private StudentService stuService;
	@Autowired
	private CurriculumPlanService cpService;
	@Autowired
	private TbClassService csService;
	@Autowired
	private EvaluationService eSerivce;
	
	@Override
	public void manage(ModelMap map) {
		map.put("bjs", csService.findAll());
		super.manage(map);
	}

	@Override
	public void edit(EvaluationInformationForm form, ModelMap map)
			throws InstantiationException, IllegalAccessException {
		UUID id = userUtils.getUser().getId();
		Student student = stuService.findById(id);
		List<CurriculumPlan> cp = cpService.findByTbClassId(student.getTbClass().getId());
		map.put("kc", cp);
		super.edit(form, map);
	}

	@Override
	public Object save(EvaluationInformationForm form) {
		form.setStudents(stuService.findById(userUtils.getUser().getId()));
		return super.save(form);
	}
	
	@RequestMapping(value="/stuSelect")
	@ResponseBody
	public Object stuSelect(String id) {
		List<Student> list = stuService.findByTbClassId(UUID.fromString(id));
		return list;
	}
	
	@RequestMapping(value="/kcSelect")
	@ResponseBody
	public Object kcSelect(String id) {
		List<CurriculumPlan> list = cpService.findByTbClassId(UUID.fromString(id));
		return list;
	}
	
	@RequestMapping(value="/coursePage")
	@ResponseBody
	public Object coursePage(TablePageable pageParam, String bjid, String stuid, String kcid) {
		PageRequest pageable = pageParam.bulidPageRequest();
		Specification<Evaluation> spec = buildSpec2(bjid, stuid, kcid);
		Page<Evaluation> page=eSerivce.findAll(spec, pageable);
		return DataGridUtils.buildResult(page);
	}

	private Specification<Evaluation> buildSpec2(String bjid, String stuid, String kcid) {
		Specification<Evaluation> specification = new Specification<Evaluation>() {

			private static final long serialVersionUID = 1L;
			
			@Override
			public Predicate toPredicate(Root<Evaluation> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules=new HashSet<>();
				if(StringUtils.hasText(bjid)) {
					Predicate name = cb.equal(root.get("evaluationRule").get("tbClassId"), UUID.fromString(bjid));
					rules.add(name);
				}
				if(StringUtils.hasText(stuid)) {
					Predicate name = cb.equal(root.get("evaluationRule").get("studentId"), UUID.fromString(stuid));
					rules.add(name);
				}
				if(StringUtils.hasText(kcid)) {
					Predicate name = cb.equal(root.get("evaluationRule").get("teachingProgrammeId"), UUID.fromString(kcid));
					rules.add(name);
				}
				return cb.and(rules.toArray(new Predicate[rules.size()]));
			}
		};
		return specification;
	}

	@Override
	public Specification<EvaluationInformation> buildSpec(EvaluationInformationForm form) {
		Specification<EvaluationInformation> specification = new Specification<EvaluationInformation>() {

			private static final long serialVersionUID = 1L;
			
			@Override
			public Predicate toPredicate(Root<EvaluationInformation> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				HashSet<Predicate> rules=new HashSet<>();
				if(userUtils.getUser() != null) {
					Predicate name = cb.equal(root.get("students").get("id"), userUtils.getUser().getId());
					rules.add(name);
				}
				return cb.and(rules.toArray(new Predicate[rules.size()]));
			}
		};
		return specification;
	}
	
}
